package com.xinqi.modules.course.chapter.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.core.enums.ChaperInitEnum;
import com.xinqi.common.core.enums.ChapterCountEnum;
import com.xinqi.common.core.enums.ChapterSelectedEnum;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.modules.course.chapter.convert.ChapterConvert;
import com.xinqi.modules.course.chapter.domain.CourseChapterEntity;
import com.xinqi.modules.course.chapter.dto.ChapterImportDTO;
import com.xinqi.modules.course.chapter.dto.ChapterSort;
import com.xinqi.modules.course.chapter.dto.ChapterSortDTO;
import com.xinqi.modules.course.chapter.dto.req.ChapterChangeIdDTO;
import com.xinqi.modules.course.chapter.dto.req.ChapterQueryDTO;
import com.xinqi.modules.course.chapter.dto.req.ChapterTreeListQueryDTO;
import com.xinqi.modules.course.chapter.dto.req.InitChapterDTO;
import com.xinqi.modules.course.chapter.dto.rsp.ChapterTreeDTO;
import com.xinqi.modules.course.chapter.mapper.CourseChapterMapper;
import com.xinqi.modules.course.chapter.param.ChapterResponseDTO;
import com.xinqi.modules.course.chapter.service.CourseChapterService;
import com.xinqi.modules.course.content.domain.CourseContentEntity;
import com.xinqi.modules.course.content.dto.CourseContentSort;
import com.xinqi.modules.course.content.mapper.CourseContentMapper;
import com.xinqi.modules.course.textbook.domain.CourseCloudTextbookContentEntity;
import com.xinqi.modules.course.textbook.manager.CourseCloudTextbookContentManager;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 课程章节表(CourseChapter)表服务实现类
 *
 * @author liuxingxing
 * @since 2023-03-08 10:10:44
 */
@Service
@RequiredArgsConstructor
public class CourseChapterServiceImpl extends BaseServiceImpl<CourseChapterMapper, CourseChapterEntity> implements CourseChapterService {

    private final ChapterConvert chapterConvert;

    private final CourseContentMapper courseContentMapper;

    private final CourseCloudTextbookContentManager textbookContentManager;

    @Override
    public void initChapter(InitChapterDTO param) {
        StringBuilder sb = new StringBuilder();
        if (Objects.equals(ChaperInitEnum.CHAPTER_TYPE.getCode(), param.getType())) {
            for (int i = 0; i < 3; i++) {
                //置空
                sb.replace(0, sb.length(), "");
                if (i == 0) {
                    sb.append("第一章");
                } else if (i == 1) {
                    sb.append("第二章");
                } else {
                    sb.append("第三章");
                }
                CourseChapterEntity parentChapter = new CourseChapterEntity();
                parentChapter.setClassId(param.getClassId());
                parentChapter.setCourseId(param.getCourseId());
                parentChapter.setPid(0L);
                parentChapter.setName(sb.toString());
                parentChapter.setSort(0);
                this.baseMapper.insert(parentChapter);
                for (int j = 0; j < 3; j++) {
                    sb.replace(0, sb.length(), "");
                    if (j == 0) {
                        sb.append("第1小节");
                    } else if (j == 1) {
                        sb.append("第2小节");
                    } else {
                        sb.append("第3小节");
                    }
                    CourseChapterEntity sonChapter = new CourseChapterEntity();
                    sonChapter.setClassId(param.getClassId());
                    sonChapter.setCourseId(param.getCourseId());
                    sonChapter.setPid(parentChapter.getId());
                    sonChapter.setName(sb.toString());
                    sonChapter.setSort(0);
                    this.baseMapper.insert(sonChapter);
                }
            }
        } else {
            for (int i = 0; i < 3; i++) {
                //置空
                sb.replace(0, sb.length(), "");
                if (i == 0) {
                    sb.append("第一周");
                } else if (i == 1) {
                    sb.append("第二周");
                } else {
                    sb.append("第三周");
                }
                CourseChapterEntity parentChapter = new CourseChapterEntity();
                parentChapter.setClassId(param.getClassId());
                parentChapter.setCourseId(param.getCourseId());
                parentChapter.setPid(0L);
                parentChapter.setName(sb.toString());
                parentChapter.setSort(0);
                this.baseMapper.insert(parentChapter);
                for (int j = 0; j < 3; j++) {
                    sb.replace(0, sb.length(), "");
                    if (j == 0) {
                        sb.append("第1课时");
                    } else if (j == 1) {
                        sb.append("第2课时");
                    } else {
                        sb.append("第3课时");
                    }
                    CourseChapterEntity sonChapter = new CourseChapterEntity();
                    sonChapter.setClassId(param.getClassId());
                    sonChapter.setCourseId(param.getCourseId());
                    sonChapter.setPid(parentChapter.getId());
                    sonChapter.setName(sb.toString());
                    sonChapter.setSort(0);
                    this.baseMapper.insert(sonChapter);
                }
            }
        }
    }

    /**
     * 新初始化章节方法
     */
    @Override
    public void initChapterNew(InitChapterDTO param) {
        String[] names = new String[]{"第一章", "第二章"};
        List<CourseChapterEntity> list = this.createChapter(names, param.getClassId(), param.getCourseId(), 0L);
        String[] sonNames = new String[]{"第1节", "第2节"};
        for (CourseChapterEntity chapter : list) {
            List<CourseChapterEntity> sonList = this.createChapter(sonNames, param.getClassId(), param.getCourseId(), chapter.getId());
            for (CourseChapterEntity timeChatper : sonList) {
                String[] timeNames = new String[]{"第1课时", "第2课时"};
                this.createChapter(timeNames, param.getClassId(), param.getCourseId(), timeChatper.getId());
            }
        }
    }

    private List<CourseChapterEntity> createChapter(String[] names, Long classId, Long courseId, Long pid) {
        List<CourseChapterEntity> list = new ArrayList<>();
        for (int i = 0; i < names.length; i++) {
            CourseChapterEntity chapter = new CourseChapterEntity();
            chapter.setClassId(classId);
            chapter.setCourseId(courseId);
            chapter.setPid(pid);
            chapter.setName(names[i]);
            chapter.setSort(i + 1);
            list.add(chapter);
        }
        this.saveBatch(list);
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeChapterAndContent(List<Long> idList) {
        boolean flag = true;
        List<Long> newIdList = idList;
        while (flag && Objects.nonNull(newIdList)) {
            newIdList = getChapterSonList(newIdList);
            if (CollectionUtils.isNotEmpty(newIdList) && newIdList.size() > 0) {
                idList.addAll(newIdList);
            } else {
                flag = false;
            }
        }
        this.deleteChapterByIds(idList.stream().distinct().collect(Collectors.toList()));
    }

    /**
     * 删除节点返回子节点ID集合
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteChapterByIds(List<Long> idList) {
        // 删除章节
        this.removeBatchByIds(idList);
         courseContentMapper.clearChapter(idList);
        return true;
    }

    /**
     * 删除节点返回子节点ID集合
     */
    @DS("slaver")
    private List<Long> getChapterSonList(List<Long> idList) {
        // 返回字节内容
        LambdaQueryWrapper<CourseChapterEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CourseChapterEntity::getPid, idList);
        List<CourseChapterEntity> sonChapters = this.baseMapper.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(sonChapters) && sonChapters.size() > 0) {
            return sonChapters.stream().map(CourseChapterEntity::getId).collect(Collectors.toList());
        } else {
            return null;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sort(ChapterSortDTO sortParam) {
        //章节排序
        if (sortParam.getChapterSorts() != null && sortParam.getChapterSorts().size() > 0) {
            List<ChapterSort> chapterSorts = sortParam.getChapterSorts();
            List<CourseChapterEntity> sortList = new ArrayList<>();
            for (ChapterSort chapterSort : chapterSorts) {
                CourseChapterEntity entity = new CourseChapterEntity();
                entity.setId(chapterSort.getChapterId());
                entity.setSort(chapterSort.getSort());
                sortList.add(entity);
            }
            this.updateBatchById(sortList);
        }
        if (sortParam.getCourseContentSorts() != null && sortParam.getCourseContentSorts().size() > 0) {
            List<CourseContentSort> courseContentSorts = sortParam.getCourseContentSorts();
            for (CourseContentSort contentSort : courseContentSorts) {
                LambdaUpdateWrapper<CourseContentEntity> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(CourseContentEntity::getContentId, contentSort.getContentId());
                CourseContentEntity entity = new CourseContentEntity();
                entity.setSort(contentSort.getSort());
                courseContentMapper.update(entity, updateWrapper);
            }
        }
    }

    /**
     * 章节目录返回树结构
     */
    @Override
    public List<ChapterTreeDTO> treeList(ChapterTreeListQueryDTO treeListQueryParam) {
        // 获取所有章节内容
        LambdaQueryWrapper<CourseChapterEntity> wrapper = new LambdaQueryWrapper<>();
        if (treeListQueryParam.getClassId() != null) {
            wrapper.eq(CourseChapterEntity::getClassId, treeListQueryParam.getClassId());
        }
        wrapper.orderByAsc(CourseChapterEntity::getSort);
        List<CourseChapterEntity> chapterEntities = this.list(wrapper);
        if (Objects.nonNull(chapterEntities) && chapterEntities.size() > 0) {
            LambdaQueryWrapper<CourseContentEntity> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(CourseContentEntity::getContentId, treeListQueryParam.getContentId());
            CourseContentEntity contentEntity = courseContentMapper.selectOne(wrapper1);

            // 转换成树结构
            List<ChapterTreeDTO> voList = chapterEntities.stream().map(item -> {
                ChapterTreeDTO vo = chapterConvert.chapterEntityToChapterVo(item);
                //根据contentId查询co_course_content，判断当前章节是否被选中
                if (Objects.nonNull(contentEntity) && Objects.nonNull(contentEntity.getChapterId())) {
                    if (Objects.equals(contentEntity.getChapterId(), item.getId())) {
                        vo.setSelected(ChapterSelectedEnum.CHAPTER_SELECTED.getCode());
                    } else {
                        vo.setSelected(ChapterSelectedEnum.CHAPTER_UNSELECTED.getCode());
                    }
                } else {
                    vo.setSelected(ChapterSelectedEnum.CHAPTER_UNSELECTED.getCode());
                }
                return vo;
            }).collect(Collectors.toList());
            //为父节点设置子节点
            List<ChapterTreeDTO> list = buildTree(voList, 0L);
            return list;
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importChapter(ChapterImportDTO importParam) {

        //获取来源章节集合
        LambdaQueryWrapper<CourseChapterEntity> sw = new LambdaQueryWrapper<>();
        sw.eq(CourseChapterEntity::getClassId, importParam.getSourceClassId())
            .orderByAsc(CourseChapterEntity::getSort);
        List<CourseChapterEntity> sourceChapters = this.list(sw);
        if (CollectionUtils.isEmpty(sourceChapters) || sourceChapters.size() == 0) {
            return;
        }

        List<ChapterChangeIdDTO> list = new ArrayList<>();
        //获取当前班级的章节
        LambdaQueryWrapper<CourseChapterEntity> tw = new LambdaQueryWrapper<>();
        tw.eq(CourseChapterEntity::getClassId, importParam.getTargetClaseId());
        tw.eq(CourseChapterEntity::getPid, YesNoNumberEnum.NO.getCode()).orderByAsc(CourseChapterEntity::getSort);
        List<CourseChapterEntity> targetParChapters = this.list(tw);
        CourseChapterEntity sourceEntity = targetParChapters.stream().filter(v -> Objects.equals(v.getPid(), 0L))
            .max(Comparator.comparing(CourseChapterEntity::getSort)).orElse(null);
        Integer sourceNum = Objects.nonNull(sourceEntity) ? sourceEntity.getSort() : 0;
        // 判断原章排序的序号是否正确
        if (Objects.nonNull(sourceEntity) && targetParChapters.size() > sourceNum) {
            sourceNum = targetParChapters.size();
        }

        // 获取导入章节的章
        List<CourseChapterEntity> parentChapters = sourceChapters.stream()
            .filter(v -> Objects.equals(v.getPid(), 0L)).collect(Collectors.toList());

        //检验章是否超过60个
        CommonErrors.BAD_REQUEST.check((targetParChapters.size() + parentChapters.size()) <= ChapterCountEnum.CHAPTER_COUNT.getCode()
            , MessageUtils.message("course.chapter.max.length.valid"));

        // 保存主章
        List<CourseChapterEntity> parent = new ArrayList<>();
        for (int i = 0; i < parentChapters.size(); i++) {
            CourseChapterEntity item = chapterConvert.newEntity(parentChapters.get(i));
            item.setId(null);
            sourceNum++;
            item.setSort(sourceNum);
            item.setCourseId(importParam.getTargetCourseId());
            item.setClassId(importParam.getTargetClaseId());
            parent.add(item);
        }
        this.saveBatch(parent);
        // 绑定新ID和旧ID
        setChangeId(parent, parentChapters, list);

        // 获取二级子节点
        List<CourseChapterEntity> sonChapters = new ArrayList<>();
        if (parentChapters != null && parentChapters.size() > 0) {
            for (CourseChapterEntity parEntity : parentChapters) {
                List<CourseChapterEntity> sonChapterList = sourceChapters.stream()
                    .filter(item -> Objects.equals(parEntity.getId(), item.getPid()))
                    .sorted(Comparator.comparing(CourseChapterEntity::getSort))
                    .collect(Collectors.toList());
                sonChapters.addAll(sonChapterList);
            }
        }
        List<CourseChapterEntity> son = sonChapters.stream().map(item -> {
            CourseChapterEntity sonItem = chapterConvert.newEntity(item);
            sonItem.setId(null);
            list.forEach(pItem -> {
                if (Objects.equals(pItem.getOldId(), item.getPid())) {
                    sonItem.setPid(pItem.getNewId());
                }
            });
            sonItem.setCourseId(importParam.getTargetCourseId());
            sonItem.setClassId(importParam.getTargetClaseId());
            return sonItem;
        }).collect(Collectors.toList());
        this.saveBatch(son);
        // 绑定新ID和旧ID
        setChangeId(son, sonChapters, list);

        // 获取三级级子节点
        List<CourseChapterEntity> timerChapters = new ArrayList<>();
        if (sonChapters != null && sonChapters.size() > 0) {
            for (CourseChapterEntity sonEntity : sonChapters) {
                List<CourseChapterEntity> timerChapterList = sourceChapters.stream()
                    .filter(item -> Objects.equals(sonEntity.getId(), item.getPid()))
                    .sorted(Comparator.comparing(CourseChapterEntity::getSort))
                    .collect(Collectors.toList());
                timerChapters.addAll(timerChapterList);
            }
        }
        List<CourseChapterEntity> timer = timerChapters.stream().map(item -> {
            CourseChapterEntity timerItem = chapterConvert.newEntity(item);
            timerItem.setId(null);
            list.forEach(pItem -> {
                if (Objects.equals(pItem.getOldId(), item.getPid())) {
                    timerItem.setPid(pItem.getNewId());
                }
            });
            timerItem.setCourseId(importParam.getTargetCourseId());
            timerItem.setClassId(importParam.getTargetClaseId());
            return timerItem;
        }).collect(Collectors.toList());
        this.saveBatch(timer);
        // 绑定新ID和旧ID
        setChangeId(timer, timerChapters, list);

        // 同步云课本
        LambdaQueryWrapper<CourseCloudTextbookContentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CourseCloudTextbookContentEntity::getRefId, list.stream().map(ChapterChangeIdDTO::getOldId).collect(Collectors.toList()));
        List<CourseCloudTextbookContentEntity> cloudBooks = textbookContentManager.list(wrapper);
        cloudBooks.forEach(item -> {
            item.setId(null);
            list.forEach(idItem -> {
                if (Objects.equals(idItem.getOldId(), item.getRefId())) {
                    item.setRefId(idItem.getNewId());
                }
            });
        });
        textbookContentManager.saveBatch(cloudBooks);
    }

    /**
     * 设置新旧章节对应的ID
     */
    private void setChangeId(List<CourseChapterEntity> targetList, List<CourseChapterEntity> sourceList, List<ChapterChangeIdDTO> list) {
        for (int i = 0; i < targetList.size(); i++) {
            ChapterChangeIdDTO vo = new ChapterChangeIdDTO();
            vo.setNewId(targetList.get(i).getId());
            vo.setOldId(sourceList.get(i).getId());
            list.add(vo);
        }
    }


    @Override
    public List<ChapterResponseDTO> selectChapterOrSonChapter(ChapterQueryDTO queryParam) {
        if (queryParam.getPid() == null) {
            queryParam.setPid(0L);
        }
        List<ChapterResponseDTO> resultList = this.baseMapper.selectChapterOrSonChapter(queryParam);
        return resultList;
    }

    public void setParentChapter(List<ChapterTreeDTO> parentChapter, Map<Long, List<ChapterTreeDTO>> sonChapterMap) {
        for (ChapterTreeDTO parent : parentChapter) {
            List<ChapterTreeDTO> sonChapter = sonChapterMap.get(parent.getId());
            parent.setChildren(sonChapter);
            if (sonChapter != null && sonChapter.size() > 0) {
                setParentChapter(sonChapter, sonChapterMap);
            }
        }
    }

    /**
     * 章节转树结构
     */
    private List<ChapterTreeDTO> buildTree(List<ChapterTreeDTO> nodes, Long pid) {
        List<ChapterTreeDTO> children = new ArrayList<>();
        for (ChapterTreeDTO node : nodes) {
            if (Objects.equals(pid, node.getPid())) {
                children.add(node);
                node.setChildren(buildTree(nodes, node.getId()));
            }
        }
        return children;
    }

    /*获取章节名称*/
    @Override
    public List<String> getChapterName(Long id) {
        return this.baseMapper.getChapterName(id);
    }

    @Override
    public void saveCourseChapter(CourseChapterEntity courseChapter) {
        //添加的章或者节不能超过30个
        Long pid = courseChapter.getPid();
        if (pid == null) {
            pid = 0L;
        }
        LambdaQueryWrapper<CourseChapterEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseChapterEntity::getClassId, courseChapter.getClassId());
        wrapper.eq(CourseChapterEntity::getPid, pid);
        long count = this.baseMapper.selectCount(wrapper);
        count = count + 1;
        // 判断章节是否超过最大值
        CommonErrors.BAD_REQUEST.check(count <= ChapterCountEnum.CHAPTER_COUNT.getCode(), MessageUtils.message("course.chapter.max.length.valid"));
        // 更具Id获取内容目前最大的排序值
        Integer sort = this.baseMapper.chapterSonMaxSort(courseChapter.getClassId(), pid);
        if (Objects.nonNull(sort)) {
            courseChapter.setSort(sort + 1);
        } else {
            courseChapter.setSort(1);
        }
        this.save(courseChapter);
    }

    @Override
    public Map<String, Object> chapterCount(Long classId) {
        Map<String, Object> res = this.baseMapper.chapterCount(classId);
        return res;
    }

    /**
     * 第x章/第x节/第x课时
     *
     * @param chapterId
     * @return
     */
    @Override
    public String selectName(Long chapterId) {
        String name = StringUtils.EMPTY;
        //查询
        CourseChapterEntity entity = this.baseMapper.selectById(chapterId);
        if (Objects.isNull(entity)) {
            return name;
        }
        name = entity.getName();
        //查询所有父节点数据
        String pIds = this.baseMapper.selectParentIds(chapterId);
        List<String> ids = Arrays.asList(pIds.split(","));
        if (CollectionUtils.isEmpty(ids)) {
            return name;
        }
        LambdaQueryWrapper<CourseChapterEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CourseChapterEntity::getId, ids);
        List<CourseChapterEntity> list = this.baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return name;
        }
        Map<Long, CourseChapterEntity> map = new HashMap<>();
        list.stream().forEach(item -> {
            map.put(item.getId(), item);
        });
        boolean flag = true;
        Long pid = entity.getPid();
        while (flag) {
            CourseChapterEntity parent = map.get(pid);
            if (Objects.isNull(parent)) {
                flag = false;
            } else {
                if (Objects.isNull(parent.getPid())) {
                    flag = false;
                } else if (Objects.equals(0L, parent.getPid())) {
                    flag = false;
                } else {
                    pid = parent.getPid();
                }

                if (StringUtils.isNotEmpty(parent.getName())) {
                    name = parent.getName() + "/" + name;
                }
            }
        }

        return name;
    }

    /**
     * 获取章节最大排序值
     *
     * @param classIds
     * @author dzy
     */
    @Override
    public List<CourseChapterEntity> maxSortChapterList(List<Long> classIds) {
        return this.baseMapper.chapterMaxSortList(classIds);
    }
}
